package com.zjhcsoft.auth.service.impl;

import static com.zjhcsoft.auth.common.constant.RedisKeyConstant.TOKEN_EXPIRE_TIME;
import static com.zjhcsoft.auth.common.constant.RedisKeyConstant.TOKEN_PREFIX;

import com.zjhcsoft.auth.common.enums.PasswordType;
import com.zjhcsoft.auth.common.enums.StatusCode;
import com.zjhcsoft.auth.common.utils.RandomUtils;
import com.zjhcsoft.auth.common.vo.Result;
import com.zjhcsoft.auth.entity.Account;
import com.zjhcsoft.auth.entity.Password;
import com.zjhcsoft.auth.entity.User;
import com.zjhcsoft.auth.entity.web.LoginBySmsRequest;
import com.zjhcsoft.auth.entity.web.LoginRequest;
import com.zjhcsoft.auth.entity.web.LoginResponse;
import com.zjhcsoft.auth.service.AccountService;
import com.zjhcsoft.auth.service.AppResourceService;
import com.zjhcsoft.auth.service.LoginService;
import com.zjhcsoft.auth.service.PasswordService;
import com.zjhcsoft.auth.service.SmsService;
import com.zjhcsoft.auth.service.UserCredentialService;
import com.zjhcsoft.auth.service.UserService;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * @Author: wzya
 * @Date: 2021/3/25
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    private RedisTemplate<String, Account> redisTemplate;
    @Autowired
    UserCredentialService credentialsService;
    @Autowired
    AppResourceService appService;
    @Autowired
    PasswordService passwordService;
    @Autowired
    AccountService accountService;
    @Autowired
    UserService userService;
    @Autowired
    SmsService smsService;

    @Override
    public Result login(LoginRequest request) {

        //登录身份校验
        Result validateResult = loginValidate(request);
        //登录流程
        if (validateResult.isSuccess()) {
            Account account = (Account) validateResult.getData();
            return loginResponse(account,PasswordType.STATIC.getCode());
        }
        return validateResult;

    }

    @Override
    public Result login(LoginBySmsRequest request) {
        if(smsService.smsMsgValidate(request.getMobile(),request.getSmsMsg())){
            Account account = accountService.getAccountByChannelAndCorporationAndCredential(request.getChannelCode(),request.getCorporationCode(),request.getMobile());
            if(null!=account){
                return loginResponse(account,PasswordType.SMS_MSG.getCode());
            }else {
                return Result.error("wrong mobile.");
            }
        }else {
            return Result.error("wrong sms msg.");
        }
    }

    @Override
    public Result keep(String token) {
        if(redisTemplate.hasKey(TOKEN_PREFIX+":"+token)){
            if(redisTemplate.expire(TOKEN_PREFIX+":"+token,TOKEN_EXPIRE_TIME, TimeUnit.MINUTES)){
                return Result.ok("token keep "+TOKEN_EXPIRE_TIME+" minutes success.");
            }else {
                return Result.error("keep failed.");
            }
        }else{
            return Result.error("invalid or expire token.");
        }
    }

    public Result loginValidate(LoginRequest request) {

        Account account = accountService.getAccountByChannelAndCorporationAndCredential(request.getChannelCode(),request.getCorporationCode(),request.getUserCredential());
        if (null != account) {
            //查询静态密码
            List<Password> passwordList = passwordService.lambdaQuery()
                    .eq(Password::getAccountId, account.getId())
                    .eq(Password::getPasswordStatus,StatusCode.ON.getCode())
                    .eq(Password::getCheckType, request.getPasswordType()).list();
            if (null != passwordList && passwordList.size() > 0) {
                return passwordList.stream().anyMatch(password -> passwordService.passwordValidate(request.getPassword(), password.getPassward())) ? Result.ok(account) : Result.error("password incorrect.");
            } else {
                return Result.error(request.getPasswordType() + " password wrong.");
            }
        } else {
            return Result.error("incorrect credential.");
        }
    }

    private Result loginResponse(Account account,String passwordType){
        User user = userService.getById(account.getSysUserId());
        //生成token
        String token = RandomUtils.randomStr(32);
        redisTemplate.opsForValue().set(TOKEN_PREFIX + ":" + token, account, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES);

        if(PasswordType.STATIC.getCode().equals(passwordType)){
            LoginResponse response = new LoginResponse();
            response.setClientNo(user.getClientNo());
            response.setClientStatus(account.getClientStatus());
            response.setContinuousErrorTimes(account.getContinuousErrorTimes());
            response.setTodayErrorTimes(account.getTodayErrorTimes());
            response.setMobile(user.getMobile());
            response.setOtpMsg(token);
            response.setIsBind(account.getIsBind());
            response.setIsCheckUser(account.getIsCheckUser());
            response.setAcrdtnLvl("");
            response.setAcrdtnMap("");
            response.setAcrdtnTckt("");
            response.setDescription("");
            return Result.ok(response);
        }else {
            LoginResponse response = new LoginResponse();
            response.setClientNo(user.getClientNo());
            response.setClientStatus(account.getClientStatus());
            response.setContinuousErrorTimes(account.getContinuousErrorTimes());
            response.setTodayErrorTimes(account.getTodayErrorTimes());
            response.setOtpMsg(token);
            response.setAcrdtnLvl("");
            response.setAcrdtnMap("");
            response.setAcrdtnTckt("");
            response.setDescription("");
            return Result.ok(response);
        }
    }
}
